﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

//this code is (CopyRight) FOMIN

namespace GL
{
    /// <summary>
    /// Управляет созданием и освобождением контекста воспроизведения OpenGL
    /// (c) Fomin
    /// </summary>
    public class glPort : IDisposable
    {
        #region fields and properties
        /// <summary>
        /// Буфер дублирован. 
        /// </summary>
        const uint PFD_DOUBLEBUFFER = 0x00000001;
        /// <summary>
        /// Буфер может передавать содержание в окно или на поверхность устройства
        /// </summary>
        const uint PFD_DRAW_TO_WINDOW = 0x00000004;
        /// <summary>
        /// Буфер поддерживает команды OpenGL.
        /// </summary>
        const uint PFD_SUPPORT_OPENGL = 0x00000020;
        /// <summary>
        /// Описывает формат пикселей изображающей поверхности.
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        class PIXELFORMATDESCRIPTOR
        {
            internal short nSize = 40;
            internal short nVersion = 1;
            internal uint dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
            internal byte iPixelType;
            internal byte cColorBits = 32;
            internal byte cRedBits;
            internal byte cRedShift;
            internal byte cGreenBits;
            internal byte cGreenShift;
            internal byte cBlueBits;
            internal byte cBlueShift;
            internal byte cAlphaBits = 8;
            internal byte cAlphaShift;
            internal byte cAccumBits = 8;
            internal byte cAccumRedBits;
            internal byte cAccumGreenBits;
            internal byte cAccumBlueBits;
            internal byte cAccumAlphaBits;
            internal byte cDepthBits = 32;
            internal byte cStencilBits = 8;
            internal byte cAuxBuffers;
            internal byte iLayerType;
            internal byte bReserved;
            internal int dwLayerMask;
            internal uint dwVisibleMask;
            internal uint dwDamageMask;
        }
        #endregion
        #region Поля и свойства
        /// <summary>
        /// Хранит идентификатор библиотечного модуля OpenGL
        /// </summary>
        static int openGLdllHandle;
        /// <summary>
        /// Хранит дескриптор формата пикселей
        /// </summary>
        PIXELFORMATDESCRIPTOR pixelFD = new PIXELFORMATDESCRIPTOR();
        /// <summary>
        /// Устанавливает и возвращает текущий контекст устройства
        /// </summary>
        public int deviceContext
        {
            private set;
            get;
        }
        /// <summary>
        /// Хранит текущий контекст воспроизведения
        /// </summary>
        int renderContext;
        /// <summary>
        /// Хранит идентификатор (хэндл) окна
        /// </summary>
        int controlHandle;
        #endregion
        #region Статические методы
        #region Методы установки формата пикселей
        /// <summary>
        /// Пытается найти формат пикселей, поддерживаемый данным контекстом устройства и 
        /// наиболее близким к данному формату.
        /// </summary>
        /// <param name="dvcContext">
        /// Определяет контекст устройства, для которого должен быть выбран формат пикселей.
        /// </param>
        /// <param name="pfd">
        /// Ссылка на экземпляр структуры типа PIXELFORMATDESCRIPTOR, 
        /// который определяет требуемый формат пикселя 
        /// </param>
        /// <returns>
        /// Индекс искомого формата пикселей. Если функция выполнена успешно, 
        /// то это значение больше нуля.
        /// Если нет, то значение равно нулю. 
        /// </returns>
        [DllImport("GDI32")]
        static extern int ChoosePixelFormat(int dvcContext,
            [MarshalAs(UnmanagedType.LPStruct)]PIXELFORMATDESCRIPTOR pfd);
        /// <summary>
        /// устанавливает формат пикселя указанного контекста устройства в формат, 
        /// определенный индексом pixelFormatIndex
        /// </summary>
        /// <param name="dvcContext">
        /// Контекст устройства, для которого устанавливается данный формат пикселя
        /// </param>
        /// <param name="pixelFormatIndex">
        /// Индекс формата пикселя
        /// </param>
        /// <param name="pfd">
        /// Ссылка на структуру 
        /// (в данном случае класс, который должен интерпретироваться как структура) типа
        /// PIXELFORMATDESCRIPTOR, которая содержит спецификацию формата пикселя. 
        /// </param>
        /// <returns>
        /// При успешном завершении возвращает TRUE, в противном случае FALSE. 
        /// </returns>
        [DllImport("GDI32")]
        static extern bool SetPixelFormat(int dvcContext, int pixelFormatIndex,
            [MarshalAs(UnmanagedType.LPStruct)]PIXELFORMATDESCRIPTOR pfd);
        #endregion
        #region Методы манипуляции с контекстами
        /// <summary>
        /// Возвращает идентификатор контекста устройства дисплея для клиентской области окна.
        /// Контекст может быть использован при вызове функций, 
        /// создающих изображение на клиентской области окна.
        /// </summary>
        /// <param name="handle">
        /// идентификатор (хэндл) окна, чей контекст должен быть возвращен
        /// </param>
        /// <returns>
        /// При успешном завершении возвращает идентификатор контекста устройства,
        ///  в противном случае 0
        /// </returns>
        [DllImport("User32")]
        static extern int GetDC(int handle);
        /// <summary>
        /// Освобождает контекст устройства для использования другими приложениями. 
        /// </summary>
        /// <param name="handle">
        /// идентификатор (хэндл) окна, чей контекст должен быть освобожден
        /// </param>
        /// <param name="dvcContext">
        /// идентификатор освобождаемого контекста устройства
        /// </param>
        /// <returns>
        /// При успешном завершении возвращает 1, в противном случае 0
        /// </returns>
        [DllImport("User32")]
        static extern int ReleaseDC(int handle, int dvcContext);
        /// <summary>
        /// Создает новый контекст воспроизведения OpenGL. 
        /// Контекст воспроизведения соответствует устройству с заданным контекстом. 
        /// Контекст воспроизведения имеет тот же формат пикселя, что и заданный контекст устройства.
        /// </summary>
        /// <param name="dvcContext">
        /// Идентификатор контекста устройства
        /// </param>
        /// <returns>
        /// При успешном завершении возвращает идентификатор контекста воспроизведения, 
        /// в противном случае 0
        /// </returns>
        [DllImport("OPENGL32.DLL")]
        static extern int wglCreateContext(int dvcContext);
        /// <summary>
        /// Уничтожает контекст воспроизведения
        /// </summary>
        /// <param name="rndContext">
        /// Идентификатор контекста воспроизведения
        /// </param>
        /// <returns>
        /// При успешном завершении возвращает TRUE, в противном случае FALSE. 
        /// </returns>
        [DllImport("OPENGL32.DLL")]
        static extern bool wglDeleteContext(int rndContext);
        /// <summary>
        /// Производит обмен содержимого переднего и заднего буферов, 
        /// если формат пикселя указанного
        /// контекста устройства включает задний буфер (двойная буферизация)
        /// </summary>
        /// <param name="dvcContext">
        /// Идентификатор контекста устройства 
        /// </param>
        /// <returns>
        /// При успешном завершении возвращает TRUE, в противном случае FALSE. 
        /// </returns>
        [DllImport("GDI32")]
        static extern bool SwapBuffers(int dvcContext);
        /// <summary>
        /// Делает указанный контекст воспроизведения OpenGL текущим контекстом 
        /// для данного подпроцесса (нити). 
        /// Все последующие вызовы команд OpenGL, сделанные в этом подпроцессе, 
        /// будут выполняться на устройстве
        /// с указанным контекстом. Функция может использоваться так же для того, чтобы текущий 
        /// контекст воспроизведения перестал быть текущим
        /// </summary>
        /// <param name="dvcContext">
        /// Идентификатор контекста устройства 
        /// </param>
        /// <param name="rndContext">
        /// Идентификатор контекста воспроизведения. Если это значение 0, 
        /// то текущий контекст воспроизведения перестает быть текущим. 
        /// В этом случае второй параметр игнорируется.
        /// </param>
        /// <returns>
        /// При успешном завершении возвращает TRUE, в противном случае FALSE. 
        /// </returns>
        [DllImport("OPENGL32.DLL")]
        static extern bool wglMakeCurrent(int dvcContext, int rndContext);
        #endregion
        /// <summary>
        /// Вводит исполняемый модуль в адресное пространство вызываемого процесса
        /// </summary>
        /// <param name="funcname">
        /// Имя исполняемого модуля
        /// </param>
        /// <returns>
        /// При успешном завершении возвращает идентификатор (хэндл) загруженного модуля, 
        /// в противном случае 0
        /// </returns>
        [DllImport("Kernel32")]
        public static extern int LoadLibrary(String funcname);
        #endregion
        #region context routine
        /// <summary>
        /// Вызывает метод wglMakeCurrent для данных контекстов устройства и воспроизведения
        /// </summary>
        /// <returns>
        /// Результат, возвращаемый методом wglMakeCurrent
        /// </returns>
        public bool MakeCurrent()
        {
            return wglMakeCurrent(deviceContext, renderContext);
        }
        /// <summary>
        /// Вызывает метод SwapBuffers для данного контекста устройства
        /// </summary>
        /// <returns>
        /// Возвращает результат метода SwapBuffers
        /// </returns>
        public bool SwapBuffers()
        {
            return SwapBuffers(deviceContext);
        }
        /// <summary>
        /// Определяет идентификатор данного окна, создает контекст устройства, 
        /// контекст воспроизведения и делает контекст воспроизведения текущим.
        /// </summary>
        /// <param name="control">
        /// данное окно
        /// </param>
        public glPort(Control control)
        {
            // Получение контекста устройства
            if (0 == (deviceContext = GetDC(controlHandle = (int)control.Handle)))
                throw new Exception("Контекст устройства для данного окна не определен.");
            // загрузка библиотеки OpenGL
            if (openGLdllHandle == 0)
                if (0 == (openGLdllHandle = LoadLibrary("OpenGL32.DLL")))
                    throw new Exception("Библиотека OPENGL32 не включена в процесс.");
            // получение индекса требуемого формата пикселя
            int pixelFormatIndex = ChoosePixelFormat(deviceContext, pixelFD);
            if (0 == pixelFormatIndex)
                throw new Exception("Формат пикселей не определен.");
            // установка формата пикселя для данного контекста устройства
            if (!SetPixelFormat(deviceContext, pixelFormatIndex, pixelFD))
                throw new Exception("Формат пикселей не установлен.");
            // создание контекста воспроизведения OpenGL для данного контекста устройства
            if (0 == (renderContext = wglCreateContext(deviceContext)))
                throw new Exception("Контекст воспроизведения не установлен.");
            // контекст воспроизведения делается текущим
            if (!wglMakeCurrent(deviceContext, renderContext))
                throw new Exception("Контекст не установлен текущим.");
        }
        /// <summary>
        /// Уничтожает контекст воспроизведения и освобождает контекст устройства текущего окна
        /// </summary>
        public void Dispose()
        {
            // контекст воспроизведения перестает быть текущим
            if (!wglMakeCurrent(0, 0))
                throw new Exception("Контекст не установлен нулем.");
            if (renderContext > 0)
                // уничтожается контекст воспроизведения
                if (!wglDeleteContext(renderContext))
                    throw new Exception("Контекст воспроизведения не освобожден.");
            if (deviceContext > 0)
                // освобождается контекст устройства
                if (0 == ReleaseDC(controlHandle, deviceContext))
                    throw new Exception("Контекст устройства не освобожден.");
            renderContext = deviceContext = 0;
        }
        #endregion
    }

    public static class gl
    {
        #region Очистка буферов
        /// <summary>
        /// Определяет значения цветов в буферах цвета. 
        /// По умолчанию все 4 составляющих цвета равны нулю
        /// </summary>
        /// <param name="red">
        /// количество красного от 0 до 1
        /// </param>
        /// <param name="green">
        /// количество зеленого от 0 до 1
        /// </param>
        /// <param name="blue">
        /// количество синего от 0 до 1
        /// </param>
        /// <param name="alpha">
        /// количество альфа-компоненты от 0 до 1, участвующей в определении эффекта прозрачности
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glClearColor")]
        public static extern void ClearColor(float red, float green, float blue, float alpha);
        /// <summary>
        /// Идентифицирует буфер цвета в методах Clear и PushAttrib.
        /// </summary>
        public const int COLOR_BUFFER_BIT = 0x00004000;
        /// <summary>
        /// Очищает буферы внутри порта вывода изображения
        /// </summary>
        /// <param name="mask">
        /// Выражение, идентифицирующее буферы, которые должны быть очищены. 
        /// Четыре маски COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT, 
        /// ACCUM_BUFFER_BIT и STENCIL_BUFFER_BIT могут быть связаны оператором | (или)
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glClear")]
        public static extern void Clear(int mask);
        /// <summary>
        /// Очищает буфер глубины
        /// </summary>
        /// <param name="depth">
        /// Значение, которым заполняется буфер глубины. По умолчанию это 1.
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glClearDepth")]
        public static extern void ClearDepth(double depth);
        #endregion
        #region Методы Get и их аргументы
        /// <summary>
        /// Аргумент Get требует возврата значения 1 параметра - режима, 
        /// в котором создается текущий список (аргумент NewList). 
        /// </summary>
        public const int LIST_MODE = 0x0B30;
        /// <summary>
        /// Аргумент Get требует возврата значения 1 параметра - текущего номера 
        /// создаваемого списка (аргумент NewList). 
        /// </summary>
        public const int LIST_INDEX = 0x0B33;

        /// <summary>
        /// Аргумент Get требует возврата значения 1 параметра - 
        /// целой символьной постоянной, определяющей какой матричный стек в настоящий момент
        /// может меняться (метод MatrixMode).
        /// </summary>
        public const int MATRIX_MODE = 0x0BA0;
        /// <summary>
        /// Аргумент Get требует возврата значения 1 параметра - 
        /// целой символьной постоянной, определяющей функцию тестирования глубины.
        /// </summary>
        public const int DEPTH_FUNC = 0x0B74;
        /// <summary>
        /// Аргумент Get требует возврата значения одного параметра - 
        /// оконной координаты zw, которым заполняются битовые плоскости 
        /// буфера глубины при его очистке. 
        /// </summary>
        public const int DEPTH_CLEAR_VALUE = 0x0B73;
        /// <summary>
        /// Аргумент Get требует возврата значения 16 параметров матрицы преобразования 
        /// от объектных координат к координатам наблюдения, находящейся на верху стека. 
        /// </summary>
        public const int MODELVIEW_MATRIX = 0x0BA6;
        /// <summary>
        /// Аргумент Get требует возврата значения 16 параметров матрицы преобразования 
        /// от координат наблюдения к координатам отсечения, находящейся на верху стека. 
        /// </summary>
        public const int PROJECTION_MATRIX = 0x0BA7;
        /// <summary>
        /// Аргумент Get требует возврата значения четырех параметров порта наблюдения 
        /// x, y, width, height.
        /// </summary>
        public const int VIEWPORT = 0x0BA2;
        /// <summary>
        /// Аргумент Get требует возврата значения одного параметра - целочисленной постоянной,
        /// определяющей функцию альфа-теста.
        /// </summary>
        public const int ALPHA_TEST_FUNC = 0x0BC1;
        /// <summary>
        /// Аргумент Get требует возврата значения одного параметра - 
        /// текущего значения параметра referenceValue метода AlphaFunc.
        /// </summary>
        public const int ALPHA_TEST_REF = 0x0BC2;
        // Аргументы метода Get, для определения числа битовых плоскостей 
        // в буферах цвета RED,GREEN,BLUE,ALPHA
        public const int RED_BITS = 0x0D52;
        public const int GREEN_BITS = 0x0D53;
        public const int BLUE_BITS = 0x0D54;
        public const int ALPHA_BITS = 0x0D55;
        // Аргумент метода Get, для определения числа битовых плоскостей в буфере глубины
        public const int DEPTH_BITS = 0x0D56;
        // Аргумент метода Get, для определения числа битовых плоскостей в буфере трафарета
        public const int STENCIL_BITS = 0x0D57;
        // Аргументы метода Get для определения числа битовых плоскостей в буфере-аккумуляторе 
        public const int ACCUM_RED_BITS = 0x0D58;
        public const int ACCUM_GREEN_BITS = 0x0D59;
        public const int ACCUM_BLUE_BITS = 0x0D5A;
        public const int ACCUM_ALPHA_BITS = 0x0D5B;
        /// <summary>
        /// Аргумент Get требует возврата значения одного параметра - размера точки
        /// </summary>
        public const int POINT_SIZE = 0x0B11;
        /// <summary>
        /// Аргумент Get требует возврата значения двух параметров - 
        /// минимального и максимально возможного размеров точки. 
        /// </summary>
        public const int POINT_SIZE_RANGE = 0x0B12;
        /// <summary>
        /// Аргумент Get требует возврата значения одного параметра – 
        /// различия в значениях размеров точки,
        /// которые учитываются в изображении.
        /// </summary>
        public const int POINT_SIZE_GRANULARITY = 0x0B13;
        /// <summary>
        /// Возвращает значения параметра с именем prmName в виде массива типа float. 
        /// </summary>
        [DllImport("OPENGL32.DLL")]
        static extern void glGetFloatv(int prmName, float[] parameters);
        /// <summary>
        /// Возвращает одно или несколько значений, отвечающих указанному типу параметра.
        /// </summary>
        /// <param name="prmName">
        /// Символьная постоянная, обозначающая имя параметра, 
        /// значения которого следует возвратить.
        /// </param>
        /// <param name="arrayLength">
        /// Длина массива возвращаемых значений
        /// </param>
        /// <returns>
        /// Массив значений
        /// </returns>
        public static float[] Get(int prmName, int arrayLength)
        {
            float[] resultArray = new float[arrayLength];
            glGetFloatv(prmName, resultArray);
            return resultArray;
        }
        /// <summary>
        /// Имя объекта-аргумента GetString для определения версии OpenGL.
        /// </summary>
        public const int VERSION = 0x1F02;
        /// <summary>
        /// Имя объекта-аргумента GetString для определения производителя OpenGL.
        /// </summary>
        public const int VENDOR = 0x1F00;
        /// <summary>
        /// Имя объекта-аргумента GetString для определения имени визуализатора OpenGL. 
        /// Возвращаемое имя специфично для конкретной аппаратной платформы компьютера.
        /// </summary>
        public const int RENDERER = 0x1F01;
        /// <summary>
        /// Возвращает указатель на объект с именем name. 
        /// </summary>
        [DllImport("OPENGL32.DLL")]
        static extern IntPtr glGetString(int name);
        /// <summary>
        /// Возвращает строку с объектом с именем name.
        /// </summary>
        public static string GetString(int name)
        {
            IntPtr i = glGetString(name);
            return Marshal.PtrToStringAnsi(i);
        }
        #endregion 
        #region Постоянные примитивов
        /// <summary>
        /// Рассматривает каждую вершину, как отдельную точку
        /// </summary>
        public const int POINTS = 0x0000;
        /// <summary>
        /// Рассматривает каждую пару вершин как независимый отрезок прямой. 
        /// Вершины 2n - 1 и 2n определяют прямую n. 
        /// Изображается N/2 прямых, где N - полное число вершин. 
        /// </summary>
        public const int LINES = 0x0001;
        /// <summary>
        /// Изображает связанную группу отрезков прямых от первой до последней вершины, 
        /// затем назад - к первой вершине. 
        /// Вершины n и n+1 определяют прямую n. Последняя прямая определяется вершинами N и 1. 
        /// Изображается N прямых, где N - полное число вершин. 
        /// </summary>
        public const int LINE_LOOP = 0x0002;
        /// <summary>
        /// Изображает связанную группу отрезков прямых от первой до последней вершины.
        /// Вершины n и n+1 определяют прямую n. 
        /// Изображается N - 1 прямая, где N - полное число вершин. 
        /// </summary>
        public const int LINE_STRIP = 0x0003;
        /// <summary>
        /// Рассматривает каждый триплет вершин, как независимый треугольник. 
        /// Вершины 3n - 2, 3n-1 и 3n определяют треугольник n. 
        /// Изображается N/3 треугольников, где N - полное число вершин. 
        /// </summary>
        public const int TRIANGLES = 0x0004;
        /// <summary>
        /// Изображает связанную группу треугольников. 
        /// Один треугольник определен для каждой вершины после первых двух вершин. 
        /// Для нечетных n, вершины n, n+1 и n+2 определяют треугольник n. 
        /// Для четных n, вершины n+1, n и n+2 определяют треугольник n. 
        /// Изображается N  - 2 треугольника, где N - полное число вершин. 
        /// </summary>
        public const int TRIANGLE_STRIP = 0x0005;
        /// <summary>
        /// Изображает связанную группу треугольников. 
        /// Один треугольник определен для каждой вершины после первых двух вершин. 
        /// Вершины 1, n+1 и n+2 определяют треугольник n. 
        /// Изображается N  - 2 треугольника, где N - полное число вершин.  
        /// </summary>
        public const int TRIANGLE_FAN = 0x0006;
        /// <summary>
        /// Рассматривает каждую группу из четырех вершин, как независимый четырехугольник. 
        /// Вершины 4n - 3, 4n - 2, 4n - 1 и 4n определяют четырехугольник n. 
        /// Изображается N/4 четырехугольника, где N - полное число вершин. 
        /// </summary>
        public const int QUADS = 0x0007;
        /// <summary>
        /// Изображает связанную группу четырехугольников. 
        /// Один четырехугольник определен для каждой пары вершин после первой пары. 
        /// Вершины 2n - 1, 2n, 2n+2 и 2n+1 определяют четырехугольник n. 
        /// Изображается N четырехугольника, где N - полное число вершин. 
        /// Заметьте, что порядок используемых вершин 
        /// для построения четырехугольника в данном примитиве
        /// отличается от того, что используется при построении независимых четырехугольников.
        /// </summary>
        public const int QUAD_STRIP = 0x0008;
        /// <summary>
        /// Изображает один выпуклый многоугольник. 
        /// Вершины от 1 до N определяют этот многоугольник.
        /// </summary>
        public const int POLYGON = 0x0009;
        /// <summary>
        /// Параметр сглаживания изображения точки. 
        /// Используется методами Get, Enable, Disable и IsEnable.
        /// </summary>
        public const int POINT_SMOOTH = 0x0B10;
        #endregion
        #region various constants
        /// <summary>
        /// Идентифицирует буфер глубины в методах Clear и PushAttrib.
        /// </summary>
        public const int DEPTH_BUFFER_BIT = 0x00000100;
        /// <summary>
        /// Параметр активации теста глубины.  
        /// </summary>
        public const int DEPTH_TEST = 0x0B71;
        /// <summary>
        /// Маска атрибутов точки.
        /// </summary>
        public const int POINT_BIT = 0x00000002;
        /// <summary>
        /// Маска атрибутов цвета
        /// </summary>
        public const int CURRENT_BIT = 0x00000001;
        // Символьные постоянные, используемые в определении функции альфа-тестирования
        public const int NEVER = 0x0200;
        public const int LESS = 0x0201;
        public const int EQUAL = 0x0202;
        public const int LEQUAL = 0x0203;
        public const int GREATER = 0x0204;
        public const int NOTEQUAL = 0x0205;
        public const int GEQUAL = 0x0206;
        public const int ALWAYS = 0x0207;
        /// <summary>
        /// Параметр активации и деактивации альфа-теста
        /// </summary>
        public const int ALPHA_TEST = 0x0BC0;
        #endregion
        #region Методы Begin, End, Vertex
        /// <summary>
        /// Begin и End ограничивают вершины примитива или группы примитивов одного типа
        /// </summary>
        /// <param name="mode">
        /// Определяет примитив или примитивы, которые будут созданы из вершин, представленных 
        /// между вызовом Begin и последующим вызовом End. 
        /// В качестве значений доступны десять символических постоянных: 
        /// POINTS, LINES, LINE_STRIP, LINE_LOOP, TRIANGLES, 
        /// TRIANGLE_STRIP, TRIANGLE_FAN, QUADS, QUAD_STRIP и POLYGON.
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glBegin")]
        public static extern void Begin(int mode);
        /// <summary>
        /// Begin и End ограничивают вершины примитива или группы примитивов одного типа.
        /// </summary>
        [DllImport("OPENGL32.DLL", EntryPoint = "glEnd")]
        public static extern void End();
        /// <summary>
        /// Методы Vertex используются внутри пары Begin/End 
        /// для определения положения вершин точки, линии и многоугольника. 
        /// Текущий цвет, направление нормали и координаты текстуры ассоциируются с вершиной, 
        /// когда вызывается Vertex.
        /// Если заданы только две координаты, то это x и y, при этом z по умолчанию равна 0.0 
        /// и четвертая координата (масштаб) w по умолчанию равна 1.0. 
        /// </summary>
        [DllImport("OPENGL32.DLL", EntryPoint = "glVertex2f")]
        public static extern void Vertex(float x, float y);
        /// <summary>
        /// Методы Vertex используются внутри пары Begin/End 
        /// для определения положения вершин точки, линии и многоугольника. 
        /// Текущий цвет, направление нормали и координаты текстуры ассоциируются с вершиной, 
        /// когда вызывается Vertex.
        /// Если заданы три координаты x, y и z, то координата w по умолчанию равна 1.0.
        /// </summary>
        [DllImport("OPENGL32.DLL", EntryPoint = "glVertex3f")]
        public static extern void Vertex(float x, float y, float z);
        /// <summary>
        /// Методы Vertex используются внутри пары Begin/End 
        /// для определения положения вершин точки, линии и многоугольника. 
        /// Текущий цвет, направление нормали и координаты текстуры ассоциируются с вершиной, 
        /// когда вызывается Vertex.
        /// </summary>
        [DllImport("OPENGL32.DLL", EntryPoint = "glVertex4f")]
        public static extern void Vertex(float x, float y, float z, float w);
        #endregion

        #region var methods
        /// <summary>
        /// Определяет диаметр растра изображаемой точки.
        /// </summary>
        /// <param name="size">
        /// Диаметр от некоторого минимального до некоторого максимального значения. 
        /// По умолчанию диаметр обычно равен 1.
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glPointSize")]
        public static extern void PointSize(float size);
        /// <summary>
        /// Активирует режимы формирования изображения командами OpenGL
        /// </summary>
        /// <param name="capability">
        /// Символьная постоянная, указывающая активируемый режим.
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glEnable")]
        public static extern void Enable(int capability);
        /// <summary>
        /// Дезактивирует режимы формирования изображения командами OpenGL
        /// </summary>
        /// <param name="capability">
        /// Символьная константа, указывающая дезактивируемый режим.
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glDisable")]
        public static extern void Disable(int capability);
        /// <summary>
        /// Определяет, активирован ли режим
        /// </summary>
        /// <param name="capability">
        /// Символьная постоянная, указывающая дезактивируемый режим.
        /// </param>
        /// <returns>
        /// true или false, в зависимости от результатов проверки
        /// </returns>
        [DllImport("OPENGL32.DLL", EntryPoint = "glIsEnabled")]
        public static extern bool IsEnabled(int capability);
        /// <summary>
        /// Заталкивает в стек копию атрибутов, определяемых аргументом mask.
        /// </summary>
        /// <param name="mask">
        /// Символьная константа, определяющая атрибуты, копируемые в стек.
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glPushAttrib")]
        public static extern void PushAttrib(int mask);
        /// <summary>
        /// Восстанавливает сохраненную копию атрибутов из стека.
        /// </summary>
        [DllImport("OPENGL32.DLL", EntryPoint = "glPopAttrib")]
        public static extern void PopAttrib();
        /// <summary>
        /// Устанавливает текущий цвет. Может иметь три или 4 параметра типа float. 
        /// Первые три параметра определяют интенсивности красного, зеленого и синего цветов 
        /// и лежат в интервале от 0 (нулевая интенсивность) до 1 (полная интенсивность). 
        /// Четвертый параметр определяет интенсивность альфа-компоненты, 
        /// или "компоненты прозрачности"  в тех же пределах. 
        /// Если альфа-компонента не задается, то ее значение равно 1 (полная интенсивность).
        /// </summary>
        [DllImport("OPENGL32.DLL", EntryPoint = "glColor3f")]
        public static extern void Color(float red, float green, float blue);
        [DllImport("OPENGL32.DLL", EntryPoint = "glColor4f")]
        public static extern void Color(float red, float green, float blue, float alpha);
        /// <summary>
        /// Маскирует воспроизведение компонент цвета red, green, blue и alpha.
        /// По умолчанию значения всех параметров true. 
        ///Значение false маскирует соответствующую компоненту.
        /// </summary>
        [DllImport("OPENGL32.DLL", EntryPoint = "glColorMask")]
        public static extern void ColorMask(bool red, bool green, bool blue, bool alpha);
        /// <summary>
        /// Устанавливает порт наблюдения.
        /// </summary>
        /// <param name="x">
        /// Определяет левую сторону прямоугольника порта наблюдения 
        /// по отношению к левой стороне окна. 
        /// По умолчанию 0.
        /// </param>
        /// <param name="y">
        /// Определяет нижнюю сторону прямоугольника порта наблюдения 
        /// по отношению к нижней стороне окна. По умолчанию 0.
        /// </param>
        /// <param name="width">
        /// Определяет ширину порта наблюдения в пикселях. 
        /// Когда контекст воспроизведения впервые привязывается 
        /// к окну значение равно ширине окна.
        /// </param>
        /// <param name="height">
        /// Определяет высоту порта наблюдения в пикселях. 
        /// Когда контекст воспроизведения впервые привязывается 
        /// к окну значение равно высоте окна.
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glViewport")]
        public static extern void Viewport(int x, int y, int width, int height);
        /// <summary>
        /// Отображает объектные координат objx, objy, objz 
        /// на оконные координаты winx, winy, winz при заданных: 
        /// матрице преобразования от объектных к координатам наблюдения modelMatrix, 
        /// матрице преобразования  projMatrix от координат наблюдения к координатам отсечения 
        /// и параметрах порта наблюдения viewport
        /// </summary>
        [DllImport("GLU32.DLL", EntryPoint = "gluProject")]
        public static extern void Project(double objx, double objy, double objz,
            double[] modelMatrix, double[] projMatrix, int[] viewport,
            out double winx, out double winy, out double winz);

        #endregion

        #region testing methods
        /// <summary>
        /// Устанавливает операцию сравнения при работе теста глубины.
        /// </summary>
        /// <param name="function">
        /// Определяет операцию сравнения глубины. Имеет значения символьных постоянных 
        /// NEVER, LESS, EQUAL, LEQUAL, GREATER, NOTEQUAL, GEQUAL и ALWAYS. 
        /// Значение по умолчанию LESS.
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glDepthFunc")]
        public static extern void DepthFunc(int function);
        /// <summary>
        /// Определяет способ тестирования по параметру альфа. 
        /// Тот или иной способ позволяет фильтровать изображение вершин в зависимости 
        /// от значения альфа-компоненты цвета.
        /// </summary>
        /// <param name="function">
        /// Определяет функцию сравнения при использовании альфа-тестирования. 
        /// Принимаются символьные постоянные NEVER, LESS, EQUAL, LEQUAL, 
        /// GREATER, NOTEQUAL, GEQUAL и ALWAYS. 
        /// По умолчанию условие альфа-тестирования установлено в ALWAYS, 
        /// то есть никакой фильтрации изображения по параметру альфа не происходит.
        /// </param>
        /// <param name="referenceValue">
        /// Задает значение параметра альфа, с которым сравнивается другое значение альфа, 
        /// поступающее в буфер вместе с изображением, например, является параметром метода Color. 
        /// Значение параметра сжимается в интервал [0; 1]. Значение по умолчанию равно 0.
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glAlphaFunc")]
        public static extern void AlphaFunc(int function, float referenceValue);

        #endregion

        #region coordinates transforms
        /// <summary>
        /// Последующие операции с матрицами относятся 
        /// к преобразованиям от координат наблюдения
        /// к координатам отсечения (действуют на стек проекционной матрицы).
        /// </summary>
        public const int PROJECTION = 0x1701;
        /// <summary>
        /// Последующие операции с матрицами относятся 
        /// к преобразованиям от объектных координат к координатам наблюдения.
        /// </summary>
        public const int MODELVIEW = 0x1700;
        /// <summary>
        /// Устанавливает тип  последующих преобразований координат.
        /// </summary>
        /// <param name="mode">
        /// Определяет тип стека матриц, на содержание которого 
        /// будут влиять последующие преобразования.
        /// Доступны три значения, 
        /// определяемые символьными постоянными MODELVIEW, PROJECTION и TEXTURE.
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glMatrixMode")]
        public static extern void MatrixMode(int mode);
        /// <summary>
        /// Заменяет текущую матрицу в стеке на единичную матрицу.
        /// </summary>
        [DllImport("OPENGL32.DLL", EntryPoint = "glLoadIdentity")]
        public static extern void LoadIdentity();
        /// <summary>
        /// Умножает содержимое стека преобразования 
        /// от координат наблюдения к координатам отсечения
        /// на матрицу ортографической (параллельной) проекции.
        /// </summary>
        /// <param name="left">
        /// Положение левой плоскости отсечения. 
        /// Значение x-координаты наблюдения, 
        /// которое проецируется на левую границу порта наблюдения.
        /// </param>
        /// <param name="right">
        /// Положение правой плоскости отсечения. 
        /// Значение x-координаты наблюдения, 
        /// которое проецируется на правую границу порта наблюдения.
        /// </param>
        /// <param name="bottom">
        /// Положение нижней плоскости отсечения. 
        /// Значение y-координаты наблюдения, 
        /// которое проецируется на нижнюю границу порта наблюдения.
        /// </param>
        /// <param name="top">
        /// Положение верхней плоскости отсечения. 
        /// Значение y-координаты наблюдения, 
        /// которое проецируется на верхнюю границу порта наблюдения.
        /// </param>
        /// <param name="near">
        /// Положение ближней плоскости отсечения.
        /// </param>
        /// <param name="far">
        /// Положение дальней плоскости отсечения.
        /// </param>
        /// <remarks>
        /// Значения (left, bottom, - near) и (right, top, - near) задают координаты наблюдения точек 
        /// на ближней плоскости отсечения, которые отображаются соответственно 
        /// на левый нижний и правый верхний угол порта наблюдения 
        /// в предположении, что начало координат наблюдения находится в точке (0, 0, 0).
        /// Значение -far задает положение дальней плоскости отсечения.
        /// Значения far и near могут быть как положительными, так и отрицательными.
        /// </remarks>
        [DllImport("OPENGL32.DLL", EntryPoint = "glOrtho")]
        public static extern void Ortho(double left, double right, double bottom, double top,
            double near, double far);
        /// <summary>
        /// Умножает содержимое стека преобразования 
        /// от координат наблюдения к координатам отсечения
        /// на матрицу ортографической (параллельной) проекции.
        /// Эквивалентен вызову метода Ortho с шестью параметрами, когда два последних параметра 
        /// имеют значения near = -1 и far = 1.
        /// </summary>
        [DllImport("GLU32.DLL", EntryPoint = "gluOrtho2D")]
        public static extern void Ortho(double left, double right, double bottom, double top);
        /// <summary>
        /// Умножает текущую матрицу на матрицу, транслирующую 
        /// начало системы координат на вектор x, y, z.
        /// </summary>
        [DllImport("OPENGL32.DLL", EntryPoint = "glTranslatef")]
        public static extern void Translate(float x, float y, float z);
        /// <summary>
        /// Умножает текущую матрицу на матрицу поворота на угол angle, измеряемый в градусах,
        /// относительно оси, заданной вектором x, y, z в объектной системе координат
        /// </summary>
        [DllImport("OPENGL32.DLL", EntryPoint = "glRotatef")]
        public static extern void Rotate(float angle, float x, float y, float z);
        /// <summary>
        /// Умножает текущую матрицу на матрицу масштабного преобразования. 
        /// Параметрами x, y, z задаются масштабные множители вдоль соответствующих осей.
        /// </summary>
        [DllImport("OPENGL32.DLL", EntryPoint = "glScalef")]
        public static extern void Scale(float x, float y, float z);
        /// <summary>
        /// Определяет преобразование наблюдения, устанавливая точку положения наблюдателя 
        /// и видимое направление вертикали.
        /// Вектор eyex, eyey, eyez определяет положение наблюдателя.
        /// Вектор centerx, centery, centerz определяет положение центра сцены.
        /// Вектор upx, upy, upz - видимое направление вертикали.
        /// </summary>
        [DllImport("GLU32.DLL", EntryPoint = "gluLookAt")]
        public static extern void LookAt(double eyex, double eyey, double eyez,
            double centerx, double centery, double centerz, double upx, double upy, double upz);
        #endregion

        #region display lists
        /// <summary>
        /// Команды создаваемого списка компилируются и выполняются
        /// </summary>
        public const int COMPILE_AND_EXECUTE = 0x1301;
        /// <summary>
        /// Команды списка только компилируются при его создании
        /// </summary>
        public const int COMPILE = 0x1300;
        /// <summary>
        /// Проверяет наличие списка
        /// </summary>
        /// <param name="list">
        /// Имя искомого списка
        /// </param>
        /// <returns>
        /// true, если список существует. В противном случае false.
        /// </returns>
        [DllImport("OPENGL32.DLL", EntryPoint = "glIsList")]
        public static extern bool IsList(uint list);
        /// <summary>
        /// Убирает списки из памяти, освобождая их имена.
        /// </summary>
        /// <param name="list">
        /// Номер первого из уничтожаемых списков
        /// </param>
        /// <param name="range">
        /// Число уничтожаемых списков
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glDeleteLists")]
        public static extern void DeleteLists(uint list, int range);
        /// <summary>
        /// Создает непрерывный ряд пустых списков
        /// </summary>
        /// <param name="range">
        /// Число создаваемых списков
        /// </param>
        /// <returns>
        /// Номер (имя) первого из созданных списков
        /// </returns>
        [DllImport("OPENGL32.DLL", EntryPoint = "glGenLists")]
        public static extern uint GenLists(int range);
        /// <summary>
        /// Создает новый список с данным именем или заменяет существующий
        /// </summary>
        /// <param name="list">
        /// Имя (номер) списка.
        /// </param>
        /// <param name="mode">
        /// Режим компиляции команд списка при его создании. 
        /// Может иметь значения COMPILE или COMPILE_AND_EXECUTE.
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glNewList")]
        public static extern void NewList(uint list, int mode);
        /// <summary>
        /// Завершает создание списка команд.
        /// </summary>
        [DllImport("OPENGL32.DLL", EntryPoint = "glEndList")]
        public static extern void EndList();
        /// <summary>
        /// Исполняет команды списка.
        /// </summary>
        /// <param name="list">
        /// Имя (номер) списка команд.
        /// </param>
        [DllImport("OPENGL32.DLL", EntryPoint = "glCallList")]
        public static extern void CallList(uint list);
        #endregion

    }


}
